\section{Cursor Concorrente}

O ResultSet Wrapper parece ser uma solução válida, no entanto, ao colocar o controlo de acesso à região crítica num nível tão alto, diminui-se a concorrência porque existe mais código que poderia ser executado em paralelo e que passa a ser executado sequencialmente. Como consequência perde-se a oportunidade de explorar sistemas com multiprocessador e diminui-se também o \emph{throughput}\cite{Goeetz2006,Oaks2004}.

Usando um driver JDBC existente implica que o melhor que se consegue é mesmo ficar nesse nível alto de concorrência. Mas implementando um driver próprio tem-se acesso ao funcionamento interno, e por isso consegue-se analisar e descobrir os pontos que são totalmente concorrentes (isto é, que podem ser executados em paralelo), e também descobrir os pontos em que se acede a recursos partilhados e tem que haver por isso acesso sequencial e exclusivo. 
Nesta secção é apresentada uma solução que começou pela implementação de um driver JDBC do tipo 4 (Native-Protocol Driver). A seguir à implementação do driver procedeu-se à inclusão do mecanismo apresentado na secção \ref{subsec:main-idea} na implementação do driver.

\subsection{Anatomia de um \emph{ResultSet}}

Nesta secção pretende-se, sem entrar em grandes detalhes, dar a entender a estrutura geral de uma implementação do \emph{ResultSet}, fazendo assim a cobertura de alguns conceitos e terminologias que ajudam a perceber as subsequentes secções.

A classe \emph{CResultSet} implementa a interface \emph{ResultSet}, comunicando com camada que implementa o protocolo \gls{tds} (\glssymbol{tds}) para executar as operações sobre o result set. 
A Figura \ref{img:resultset-overview} apresenta o diagrama de classes simplificado da implementação do \emph{ResultSet}.

\begin{figure}[H]
  \caption{Visão geral da implementação do \emph{ResultSet}}
  \label{img:resultset-overview}
  \centering
  \includegraphics[width=14.0cm]{images/model/resultset-overview}
\end{figure}

A Tabela \ref{tab:cresultset-atrib} possui uma descrição dos atributos da classe \emph{CResultSet}.

\begin{table}[H]
  \caption{Descrição dos atributos da implementação do \emph{ResultSet}.}
  \label{tab:cresultset-atrib}
  \centering
  \begin{tabular}{|l|p{11cm}|}
    \hline
    \head{Atributo} & \head{Descrição}
    \\ \hline
    cursor      & Identificador do cursor do servidor.
                  É obtido na resposta do servidor ao pedido de criação do cursor (ver secção \ref{sec:spcursoropen}). 
    \\ \hline
    currentRow  & Número da linha actual do cursor cliente. 
    \\ \hline
    rsIndex     & Índice para aceder ao cache. 
    \\ \hline
    tdsResultSet & Cache do result set.
    \\ \hline
  \end{tabular}
\end{table}

Apesar de o ResultSet operar linha a linha interagindo com o cursor do servidor, cada instância de uma implementação do ResultSet possui em memória um conjunto de linhas, isto é, possui um \emph{cache}, de modo a diminuir o número de mensagens trocadas entre o cliente e o servidor. 
Tal como na arquitectura de computadores em que os processadores usam o \emph{princípio da localidade de referência}\cite{COD2007,ECOA2003} e transferem para a memória de mais alto nível não só os dados pedidos, mas um bloco de dados adjacentes; no acesso a uma linha de um result set existe uma grande probabilidade de uma linha próxima ser também utilizada (pelo princípio), é por isso uma boa estratégia, sempre que existe o pedido de uma linha que não se encontra na cache, transferir um bloco de linhas adjacentes.

A classe \emph{CResultSet} possui um objecto que implementa a interface \emph{ITDSResultSet}. Esse objecto corresponde ao cache referido anteriormente e possui o result set formatado de acordo com o protocolo TDS. O cache essencialmente é constituído por uma lista com as linhas do result set e possui ainda a descrição das colunas que formam uma linha, nessa descrição está presente, por exemplo, o tipo de dados da coluna e o respectivo nome.

O cache é indexado usando a variável \texttt{rsIndex}, cuja gama de valores vai desde zero até ao tamanho da cache. O tamanho da cache é definido pelo método setFetchSize da interface ResultSet. A variável rsIndex para além de ser utilizada para ler o conteúdo de uma linha do result set, pode também ser utilizada nas operações de actualização e remoção (se o tipo de result set as suportar).
O cursor servidor actualiza o result set utilizando um índice relativo ao seu buffer (ver apêndice \ref{ap:cursorsp}, particularmente a secção \ref{sec:spcursor}), esse índice corresponde exactamente ao valor de rsIndex. A operação de inserção ignora este valor, porque as inserções são realizadas após a última linha do result set.

O número da linha actual do result set é guardado pela variável \texttt{currentRow}, cujo valor varia na gama 1 até ao número total de linhas seleccionadas pela execução da \gls{statement}. O seu valor pode ser obtido a partir do método getRow da interface ResultSet, e tem particular importância para o funcionamento interno de CResultSet na verificação da necessidade de efectuar um \gls{fetch} de um novo conjunto de linhas. Se o valor de currentRow não estiver contido na gama de linhas que o cache possui, então é preciso pedir novas linhas ao cursor do servidor.

\input{chapters/metodo/solucao-cursor-individual}
\input{chapters/metodo/solucao-cursor-partilhado}
